home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Graphics Plus
/
Graphics Plus.iso
/
amiga
/
gui
/
prcgntn1.lha
/
Precognition
/
source
/
pcgWindow.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-12-23
|
23KB
|
979 lines
#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/ports.h>
#include <stdio.h>
#include "pcgWindow.h"
#include "pcgWindowClass.h"
#include "Precognition_Utils.h"
#include "minmax.h"
#include <proto/exec.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include "amigamem.h"
extern struct IntuitionBase *IntuitionBase;
Screen *pcgWindow_GetScreen( pcgWindow *self )
{
Screen *screen;
Window *iwindow;
if (iwindow = iWindow(self))
screen = self->Window->WScreen;
else
screen = self->NewWindow.Screen;
return screen;
}
BOOL pcgWindow_SanityCheck( pcgWindow *self,
Point *location,
Point *size )
/* returns TRUE if location was changed. */
{
Screen *screen;
BOOL loc_changed = FALSE;
/* printf("SanityCheck before: Location=%d,%d, Size=%d,%d\n",*/
/* location->x, location->y, size->x, size->y );*/
screen = pcgWindow_GetScreen(self);
if (screen != NULL)
{
size->x = MIN( size->x, screen->Width );
size->y = MIN( size->y, screen->Height );
/* size is now ok, so check location. */
if (location->x + size->x >= screen->Width)
{
location->x = screen->Width - size->x;
loc_changed = TRUE;
}
if (location->y + size->y >= screen->Height)
{
location->y = screen->Height - size->y;
loc_changed = TRUE;
}
}
return loc_changed;
}
Point pcgWindow_Location( pcgWindow *self )
{
Point location;
struct Window *iwindow;
if (iwindow = iWindow(self))
{
location.x = iwindow->LeftEdge;
location.y = iwindow->TopEdge;
}
else
{
location = self->Location;
}
return location;
}
Point pcgWindow_Size( pcgWindow *self )
{
Point size;
struct Window *iwindow;
if (iwindow = iWindow(self))
{
size.x = iwindow->Width;
size.y = iwindow->Height;
}
else
{
size = self->Size;
}
return size;
}
Point pcgWindow_SetLocation( pcgWindow *self, WORD LeftEdge, WORD TopEdge )
{
Point location, new_loc, size;
WORD dx, dy;
struct Window *iwindow;
location = Location(self);
size = Size(self);
new_loc.x = LeftEdge;
new_loc.y = TopEdge;
pcgWindow_SanityCheck( self, &new_loc, &size );
/*printf("pcgWindow_SetLocation\n");*/
if (iwindow = iWindow(self))
{
dx = new_loc.x - location.x;
dy = new_loc.y - location.y;
MoveWindow( iwindow, dx, dy );
self->Location.x = self->NewWindow.LeftEdge = iwindow->LeftEdge;
self->Location.y = self->NewWindow.TopEdge = iwindow->TopEdge;
}
else
{
self->Location.x = self->NewWindow.LeftEdge = new_loc.x;
self->Location.y = self->NewWindow.TopEdge = new_loc.y;
}
return self->Location;
}
Point pcgWindow_SetSize( pcgWindow *self, WORD width, WORD height )
{
Point size, location, new_size;
WORD dx, dy;
struct Window *iwindow;
new_size.x = width;
new_size.y = height;
location = Location(self);
if (pcgWindow_SanityCheck( self, &location, &new_size ))
{
/* In order to set this size, you have to first move the window. */
SetLocation( self, location.x, location.y );
}
/*printf("pcgWindow_SetSize\n");*/
if (iwindow = iWindow(self))
{
/*printf("window is open.\n");*/
size = Size(self);
dx = new_size.x - size.x;
dy = new_size.y - size.y;
/*printf("size.x,y = (%d,%d), dx,dy=(%d,%d)\n", size.x, size.y, dx, dy );*/
SizeWindow( iwindow, dx, dy );
self->NewWindow.Width = self->Size.x = iwindow->Width;
self->NewWindow.Height = self->Size.y = iwindow->Height;
}
else
{
self->Size.x = self->NewWindow.Width = new_size.x;
self->Size.y = self->NewWindow.Height = new_size.y;
}
return self->Size;
}
struct Window *pcgWindow_OpenWindow( pcgWindow *self )
{
/*printf("pcgWindow_OpenWindow\n");*/
if (self->Window) return self->Window;
if (self->SharedUserPort)
self->Window = OpenWindowWithSharedUserPort(
&self->NewWindow, self->SharedUserPort );
else /* normal open window. */
self->Window = OpenWindow( &self->NewWindow );
if (self->Window)
{
self->Window->UserData = (APTR) self;
if (self->MenuStrip)
SetMenuStrip( self->Window, self->MenuStrip );
}
return self->Window;
}
void pcgWindow_CloseWindow( pcgWindow *self )
{
Window *w;
Point size, loc;
if (w = self->Window)
{
/* Record size and location (for possible reopen). */
loc = Location(self);
size = Size(self);
if (w->MenuStrip) ClearMenuStrip( w );
if (self->SharedUserPort)
{
/* Cannot simply close a SharedUserPort window, because
* Intution will deallocate the UserPort, and some other
* applications may be using them. (Instant GURU)
*/
CloseWindowWithSharedUserPort( w );
}
else
CloseWindow( w );
self->Window = NULL;
SetSize( self, size.x, size.y );
SetLocation( self, loc.x, loc.y );
}
}
pcgWindow *pcgWindow_InteractorWindow( pcgWindow *self ) { return self; }
Gadget *pcgWindow_FirstGadget( pcgWindow *self )
{
Gadget *g;
struct Window *iwindow;
if (iwindow = iWindow(self))
{
g = iwindow->FirstGadget;
}
else
{
g = self->NewWindow.FirstGadget;
}
return g;
}
USHORT pcgWindow_nGadgets( pcgWindow *self )
{
Gadget *g;
USHORT count = 0;
for (g = FirstGadget(self); g!=NULL; g=g->NextGadget )
count++;
return count;
}
ULONG pcgWindow_IDCMPFlags( pcgWindow *self )
{
struct Window *iwindow;
if (iwindow=iWindow(self))
return iwindow->IDCMPFlags;
else
return self->NewWindow.IDCMPFlags;
}
USHORT pcgWindow_ClaimEvent( pcgWindow *self, IntuiMessage *event )
{
struct Window *iwindow;
USHORT response = 0;
Interactor *iactor;
if (iwindow = iWindow(self))
{
if (event->IDCMPWindow = iwindow)
{
response = RESPONDED;
for (iactor = self->FirstInteractor; iactor!=NULL; iactor=iactor->Next)
{
response |= ClaimEvent(iactor, event);
if (response & CONSUMED_EVENT)
break;
}
}
}
return response;
}
void pcgWindow_AddGraphicObject( pcgWindow *window,
GraphicObject *graphic )
{
GraphicObject *g;
if (window->FirstGraphic)
{
for (g = window->FirstGraphic;
g->Next != NULL;
g = g->Next );
g->Next = graphic;
}
else
window->FirstGraphic = graphic;
}
void pcgWindow_RemoveGraphicObject( pcgWindow *window,
GraphicObject *graphic )
{
GraphicObject *g;
if (window->FirstGraphic)
{
if (window->FirstGraphic == graphic)
{
window->FirstGraphic = graphic->Next;
}
else
{
for( g = window->FirstGraphic;
g != NULL;
g = g->Next )
{
if (g->Next == graphic)
{
g->Next = graphic->Next;
break;
}
}
}
}
graphic->Next = NULL;
}
void pcgWindow_AddInteractor( pcgWindow *window,
Interactor *interactor )
{
Interactor *iactor;
ULONG flags;
struct Window *iwindow;
SetInteractorWindow( interactor, window );
if (nGadgets(interactor)) /* Interactor has gadget(s) */
{
if (iwindow = iWindow(window))
{
AddGList( iwindow, FirstGadget(interactor),
(USHORT) ~0, nGadgets(interactor), NULL );
}
else
{
/* Add Gadgets to last gadget of window. */
if (window->NewWindow.FirstGadget)
{
ChainGadgets( window->NewWindow.FirstGadget,
FirstGadget(interactor) );
}
else
window->NewWindow.FirstGadget = FirstGadget(interactor);
}
}
/* add this interactor to chain of interactors. */
if (window->FirstInteractor)
{
for (iactor = window->FirstInteractor;
iactor->Next != NULL;
iactor = iactor->Next );
iactor->Next = interactor;
}
else
window->FirstInteractor = interactor;
/* Add IDCMP flags */
flags = IDCMPFlags( window ) | IDCMPFlags( interactor );
SetIDCMPFlags( window, flags );
/*printf("AddIActor: %s IDCMPFlags=%d\n",*/
/* ClassName( interactor ), IDCMPFlags(interactor) );*/
}
ULONG pcgWindow_SetIDCMPFlags( pcgWindow *self, ULONG newflags )
{
struct Window *iwindow;
self->NewWindow.IDCMPFlags = newflags;
/*printf("SetIDCMPFlags: %d\n", newflags );*/
if (iwindow = iWindow(self)) /* window is open */
{
ModifyIDCMP( iwindow, newflags );
}
return IDCMPFlags(self);
}
struct RastPort *pcgWindow_RPort( pcgWindow *self )
{
if (self->Window)
return self->Window->RPort;
return NULL;
}
void pcgWindow_Refresh( pcgWindow *window )
{
GraphicObject *graphic;
Interactor *interactor;
RastPort *rport;
struct Window *iwindow;
if (iwindow = iWindow(window))
{
RefreshWindowFrame(iwindow);
rport = RPort( window );
/* Draw window graphics */
for( graphic = window->FirstGraphic;
graphic != NULL;
graphic = graphic->Next )
{
Render( graphic, rport );
}
/* Draw interactors */
for ( interactor = window->FirstInteractor;
interactor != NULL;
interactor = interactor->Next )
{
Refresh( interactor );
}
}
}
BOOL pcgWindow_Activate( pcgWindow *self, BOOL activate )
{
struct Window *iwindow;
if (iwindow = iWindow(self))
{
if (activate)
{
ActivateWindow( iwindow );
}
}
return isActive(self);
}
#define DONT_CHANGE_SCREEN_TITLE ((char*)-1)
BOOL pcgWindow_SetTitle( pcgWindow *self,
char *title )
{
struct Window *iwindow;
char *t;
Afree( Title(self) );
t = Astrdup(title);
if (iwindow = iWindow(self))
{
SetWindowTitles( iwindow, t, DONT_CHANGE_SCREEN_TITLE );
}
self->NewWindow.Title = t;
return TRUE;
}
char *pcgWindow_Title( pcgWindow *self )
{
return (char*) self->NewWindow.Title;
}
struct Window *pcgWindow_iWindow( pcgWindow *self )
{
return self->Window;
}
struct Window *pcgOpenWindow( pcgWindow *self )
{
struct pcgWindowClass *class;
struct Window *result = NULL;
/*printf("pcgOpenWindow\n");*/
if (class = (struct pcgWindowClass *) self->isa)
{
if (class->OpenWindow)
result = (*class->OpenWindow)( self );
}
if (result)
Refresh(self);
return result;
}
void pcgCloseWindow( pcgWindow *self )
{
struct pcgWindowClass *class;
if (class = (struct pcgWindowClass *) self->isa)
{
if (class->CloseWindow)
(*class->CloseWindow)( self );
}
}
struct Window *iWindow( pcgWindow *self )
{
struct pcgWindowClass *class;
struct Window *result = NULL;
if (class = (struct pcgWindowClass *) self->isa)
{
if (class->iWindow)
result = (*class->iWindow)( self );
}
return result;
}
RastPort *RPort( pcgWindow *self )
{
struct pcgWindowClass *class;
struct RastPort *result = NULL;
if (class = (struct pcgWindowClass *) self->isa)
{
if (class->RPort)
result = (*class->RPort)( self );
}
return result;
}
ULONG SetIDCMPFlags( pcgWindow *self, ULONG flags )
{
struct pcgWindowClass *class;
if (class = (struct pcgWindowClass *) self->isa)
{
if (class->SetIDCMPFlags)
flags = (*class->SetIDCMPFlags)( self, flags );
}
return flags;
}
void AddGraphicObject( pcgWindow *self, GraphicObject *graphic )
{
struct pcgWindowClass *class;
if (class = (struct pcgWindowClass *) self->isa)
{
if (class->AddGraphicObject)
(*class->AddGraphicObject)( self, graphic );
}
}
void RemoveGraphicObject( pcgWindow *self, GraphicObject *graphic )
{
struct pcgWindowClass *class;
if (class = (struct pcgWindowClass *) self->isa)
{
if (class->RemoveGraphicObject)
(*class->RemoveGraphicObject)( self, graphic );
}
}
void AddInteractor( pcgWindow *self, Interactor *interactor )
{
struct pcgWindowClass *class;
if (class = (struct pcgWindowClass *) self->isa)
{
if (class->AddInteractor)
(*class->AddInteractor)( self, interactor );
}
}
void RemoveInteractor( pcgWindow *self, Interactor *interactor )
{
struct pcgWindowClass *class;
if (class = (struct pcgWindowClass *) self->isa)
{
if (class->RemoveInteractor)
(*class->RemoveInteractor)( self, interactor );
}
}
void AddWindowPObject( pcgWindow *window, GraphicObject *obj )
{
if (isa(obj, InteractorClass()))
AddInteractor(window, (Interactor*) obj);
else
AddGraphicObject(window, obj );
}
void RemoveWindowPObject( pcgWindow *window, GraphicObject *obj )
{
if (isa(obj, InteractorClass()))
RemoveInteractor(window, (Interactor*) obj);
else
RemoveGraphicObject(window, obj );
}
void AddMenuStrip( pcgWindow *self, Menu *menustrip )
{
struct pcgWindowClass *class;
if (class = (struct pcgWindowClass *) self->isa)
{
if (class->AddMenuStrip)
(*class->AddMenuStrip)( self, menustrip );
}
}
void RemoveMenuStrip( pcgWindow *self )
{
struct pcgWindowClass *class;
if (class = (struct pcgWindowClass *) self->isa)
{
if (class->RemoveMenuStrip)
(*class->RemoveMenuStrip)( self );
}
}
void pcgWindow_RemoveIactorGadgets( pcgWindow *self,
Interactor *interactor )
{
Gadget *gadget, *prev_gadget, *next_gadget, *last_gadget;
USHORT i, ngadgets;
struct Window *iwindow;
if (gadget = FirstGadget(interactor))
{
ngadgets = nGadgets(interactor);
if (iwindow = iWindow(self)) /* window is open. */
{
RemoveGList( iwindow, gadget, ngadgets );
}
else /* window is not open. */
{
next_gadget = gadget;
for( i=0; i<ngadgets; i++)
{
last_gadget = next_gadget;
next_gadget = next_gadget->NextGadget;
}
last_gadget->NextGadget = NULL;
if (self->NewWindow.FirstGadget == gadget)
{
self->NewWindow.FirstGadget = next_gadget;
}
else
{
for( prev_gadget = self->NewWindow.FirstGadget;
prev_gadget != NULL;
prev_gadget = prev_gadget->NextGadget )
{
if (prev_gadget->NextGadget == gadget)
{
prev_gadget->NextGadget = next_gadget;
break;
}
}
}
}
}
}
void pcgWindow_RemoveInteractor( pcgWindow *self,
Interactor *interactor )
{
Interactor *iactor;
ULONG flags = 0;
SetInteractorWindow( interactor, NULL );
if (self->FirstInteractor)
{
if (self->FirstInteractor == interactor)
self->FirstInteractor = interactor->Next;
else
{
for( iactor = self->FirstInteractor;
iactor != NULL;
iactor = iactor->Next )
{
if (iactor->Next == interactor)
{
iactor->Next = interactor->Next;
pcgWindow_RemoveIactorGadgets( self, interactor );
break;
}
}
}
interactor->Next = NULL;
}
/* Compute needed IDCMP flags w/o this responder. */
flags = self->IDCMPFlags;
for( iactor = self->FirstInteractor;
iactor != NULL;
iactor = iactor->Next )
flags |= IDCMPFlags(iactor);
SetIDCMPFlags( self, flags );
}
BOOL pcgWindow_EnableIactor( pcgWindow *self, BOOL enable )
{
Window *iwindow;
Interactor *iactor;
Gadget *gadget;
Menu *menu;
UWORD mcount;
if (iwindow = self->Window)
{
iactor = self->FirstInteractor;
gadget = (iactor) ? FirstGadget(iactor) : NULL;
if (enable)
{
if (gadget)
AddGList( iwindow, gadget, nGadgets(self), -1, NULL );
SetIDCMPFlags( self, self->NewWindow.IDCMPFlags );
/* enable menus. */
for( menu = iwindow->MenuStrip, mcount=0;
menu != NULL;
menu = menu->NextMenu, mcount++ )
OnMenu( iwindow, mcount | (NOITEM<<5) );
ClearPointer( iwindow );
}
else /* disable it. */
{
if (gadget)
RemoveGList( iwindow, gadget, -1 );
if (self->SharedUserPort)
{
/* Can't set IDCMPport to NULL if its shared. */
ModifyIDCMP( iwindow, REFRESHWINDOW );
}
else
{
ModifyIDCMP( iwindow, 0 );
}
SetWaitPointer( iwindow );
/* disable menus. */
for( menu = iwindow->MenuStrip, mcount=0;
menu != NULL;
menu = menu->NextMenu, mcount++ )
OffMenu( iwindow, mcount | (NOITEM<<5) );
}
}
else return FALSE;
}
void pcgWindow_AddMenuStrip( pcgWindow *window, Menu *menustrip )
{
if (window->MenuStrip) /* window already has a menu */
{
RemoveMenuStrip(window);
}
window->MenuStrip = menustrip;
if (window->Window) /* Window is open */
{
SetMenuStrip(window->Window, menustrip);
}
}
void pcgWindow_RemoveMenuStrip( pcgWindow *window )
{
window->MenuStrip = NULL;
if (window->Window) /* its open. */
{
ClearMenuStrip(window->Window);
}
}
void pcgWindow_Erase( pcgWindow *self )
{
Window *window;
RastPort *rport;
window = iWindow(self);
rport = RPort(self);
SetDrMd ( rport, JAM2 );
SetAPen ( rport, 0 );
RectFill( rport, 0,0, window->Width, window->Height );
}
void pcgWindow_Render( pcgWindow *self, RastPort *dontcare )
{
pcgWindow_Erase( self );
Refresh ( self );
}
BOOL pcgWindow_elaborated = FALSE;
struct pcgWindowClass pcgWindow_Class;
void pcgWindowClass_Init( struct pcgWindowClass *class )
{
InteractorClass_Init( (struct InteractorClass *) class );
class->isa = InteractorClass();
class->ClassName = "pcgWindow";
class->CleanUp = NULL;
class->Location = pcgWindow_Location;
class->SetLocation = pcgWindow_SetLocation;
class->Size = pcgWindow_Size;
class->AskSize = NULL;
class->SetSize = pcgWindow_SetSize;
/*class->SizeFlags = GraphicObject_SizeFlagsAll;*/
class->Render = pcgWindow_Render;
class->InteractorWindow = pcgWindow_InteractorWindow;
class->SetInteractorWindow = NULL;
class->FirstGadget = pcgWindow_FirstGadget;
class->nGadgets = pcgWindow_nGadgets;
class->IDCMPFlags = pcgWindow_IDCMPFlags;
class->ClaimEvent = pcgWindow_ClaimEvent;
class->Respond = NULL;
class->Refresh = pcgWindow_Refresh;
class->EnableIactor = pcgWindow_EnableIactor;
/* class->isEnabled = pcgWindow_isEnabled;*/
class->Activate = pcgWindow_Activate;
class->isActive = NULL; /* pcgWindow_isActive;*/
class->SetTitle = pcgWindow_SetTitle;
class->Title = pcgWindow_Title;
class->OpenWindow = pcgWindow_OpenWindow;
class->CloseWindow = pcgWindow_CloseWindow;
class->iWindow = pcgWindow_iWindow;
class->RPort = pcgWindow_RPort;
class->SetIDCMPFlags = pcgWindow_SetIDCMPFlags;
class->AddGraphicObject = pcgWindow_AddGraphicObject;
class->RemoveGraphicObject = pcgWindow_RemoveGraphicObject;
class->AddInteractor = pcgWindow_AddInteractor;
class->RemoveInteractor = pcgWindow_RemoveInteractor;
class->AddMenuStrip = pcgWindow_AddMenuStrip;
class->RemoveMenuStrip = pcgWindow_RemoveMenuStrip;
}
struct pcgWindowClass *pcgWindowClass( void )
{
if (! pcgWindow_elaborated)
{
pcgWindowClass_Init( &pcgWindow_Class );
pcgWindow_elaborated = TRUE;
}
return &pcgWindow_Class;
}
void pcgWindow_Init( pcgWindow *self,
UWORD leftedge,
UWORD topedge,
UWORD width,
UWORD height,
UWORD minwidth,
UWORD minheight,
UWORD maxwidth,
UWORD maxheight,
char *title,
ULONG IDCMPFlags,
ULONG flags,
struct Screen *screen )
{
Interactor_Init( self );
self->isa = pcgWindowClass();
self->Window = NULL;
self->FirstInteractor = NULL;
self->FirstGraphic = NULL;
self->SharedUserPort = NULL;
self->MenuStrip = NULL;
self->NewWindow.BlockPen = 1;
self->NewWindow.DetailPen = 0;
self->NewWindow.IDCMPFlags = self->IDCMPFlags = IDCMPFlags;
self->NewWindow.Flags = flags;
self->NewWindow.FirstGadget = NULL;
self->NewWindow.CheckMark = NULL;
self->NewWindow.Title = NULL;
self->NewWindow.BitMap = NULL;
self->NewWindow.MinWidth = minwidth;
self->NewWindow.MinHeight = minheight;
self->NewWindow.MaxWidth = maxwidth;
self->NewWindow.MaxHeight = maxheight;
if (screen)
{
self->NewWindow.Type = CUSTOMSCREEN;
self->NewWindow.Screen = screen;
}
else
{
self->NewWindow.Type = WBENCHSCREEN;
self->NewWindow.Screen = NULL;
}
/*
** Have to have an initial size before you can call
** SetSize or SetLocation
*/
self->Location.x = self->NewWindow.LeftEdge = 0;
self->Location.y = self->NewWindow.TopEdge = 0;
self->Size.x = self->NewWindow.Width = 0;
self->Size.y = self->NewWindow.Height = 0;
SetSize( self, width, height );
SetLocation( self, leftedge, topedge );
SetTitle( self, title );
}